/*
* @author : TF-BJ-C064
* @creation : 2014-7-29 下午2:49:26
* @description : 
*
*/

package com.tool.tmap;

import java.io.IOException;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import com.action.system.qrservlet;


public class Convert {
	
	private Logger log = Logger.getLogger(qrservlet.class);
	
	public static String BAIDU_KEY = "15EdmORyQbzDsGOQHiTsW2oh";
	public static String BMAP_CONVERT_URL = "http://api.map.baidu.com/geoconv/v1/?" ;
	
	public static void main(String argv[]){

		double x1=116.397428;
		double y1=39.90923 ;
		BMap2GPS(x1, y1);
		
	}
	
	/**
	 *  转换百度地图坐标2 GPS坐标
	 * <p>Title: BMap2GPS</p>
	 * <p>Description:
	 * 		百度地图官网只提供了其他地图坐标转换为百度地图坐标，但是百度地图坐标并没有提供百度地图坐标转换为其他地图的坐标
	 * 
	 *    From : http://hunray.iteye.com/blog/1404129		
	 * 		百度地图API中，有GPS坐标转百度坐标的功能 
			http://dev.baidu.com/wiki/static/map/API/examples/?v=1.2&0_6#0&6 
			
			http接口是：http://api.map.baidu.com/ag/coord/convert?from=0&to=4&x=116.397428&y=39.90923&callback=BMap.Convertor.cbk_7594 
			返回结果坐标是通过base64加密的。 
			这个转换算法百度是不会公开的，而且百度也没有提供百度坐标转成GPS坐标功能，这里我用了取巧的办法。 
			
			百度坐标和GPS坐标转换在很近的距离时偏差非常接近。 
			假设你有百度坐标：x1=116.397428，y1=39.90923 
			把这个坐标当成GPS坐标，通过接口获得他的百度坐标：x2=116.41004950566，y2=39.916979519873 
			
			通过计算就可以得到GPS的坐标： 
			x = 2*x1-x2，y = 2*y1-y2 
			x=116.38480649434001 
			y=39.901480480127 
			
			在http://dev.baidu.com/wiki/static/map/API/examples/?v=1.2&0_6#0&6 将此坐标输入GPS数据项中得到的结果是：116.39743826208,39.909194650838 
	 * 			
	 * </p>
	 * @param longitude
	 * @param latitude
	 * @return
	 */
	public static GPSPoint BMap2GPS(double longitude, double latitude){
		
		GPSPoint p1 = new GPSPoint(longitude, latitude);
		GPSPoint p2 = Convert.GPS2BMap(p1.getX(), p1.getY(), null);//把这个坐标当成GPS坐标，通过接口获得他的百度坐标
		
		//通过计算就可以得到GPS的坐标 p
		GPSPoint gps = new GPSPoint();
		gps.setX( 2*p1.getX() - p2.getX());
		gps.setY( 2*p1.getY() - p2.getY());
		
		//将此GPS坐标通过接口获得他的百度坐标,输出对比
		GPSPoint p3 = Convert.GPS2BMap(gps.getX(), gps.getY(), null);
		System.out.println("p1="+p1.toString() );
		System.out.println("p2="+p2.toString() );
		System.out.println("gps="+gps.toString() );
		System.out.println("p3"+p3.toString() );
		
		return gps;
	}
	
	
	/**
	 * 转换GPS坐标2百度地图坐标
	 * <p>Title: GPS2BMap</p>
	 * <p>Description: 
	 * 		通过百度地图API转换GPS坐标2百度坐标
	 * </p>
	 * @param longitude : 经度
	 * @param latitude  : 纬度
	 * @see com.tool.tmap.Convert#BMap2GPSHttp(double longitude, double latitude, String baiduconverturl)	
	 * @return
	 * 		com.tool.tmap.GPSPoint
	 */
	public static GPSPoint GPS2BMap(double longitude, double latitude, String url){
		GPSPoint point = null;
		//{"status":0,"result":[{"x":114.23074898012,"y":29.579085062759}]}
		String html = Convert.GPS2BMapHttp(longitude, latitude, null);
		if(html!=null){
			JSONObject json = JSONObject.fromObject(html);
			if(json==null)
				return null;
			try{
				Integer status = json.getInt("status");
				if(status!=null && status==0){
					JSONArray array = json.getJSONArray("result");
					if(array==null || array.size()<1)
						return null;
					json = array.getJSONObject(0);
					if(json!=null){
						point = new GPSPoint(json.getDouble("x"), json.getDouble("y"));
					}
				}
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		return point;
	}

	public static boolean GPS2BMap(GPSPoint [] points){
		
		String html = GPS2BMapHttp(points);
		if(html==null || html.trim().isEmpty())
			return false;
		if(html!=null){
			JSONObject json = JSONObject.fromObject(html);
			if(json==null)
				return false;
			try{
				Integer status = json.getInt("status");
				if(status!=null && status==0){
					JSONArray array = json.getJSONArray("result");
					if(array==null || array.size()<1)
						return false;
					if(array.size() != points.length){
						throw new Exception("坐标转换错误,转换前后不一样, points.length="+points+" array.size="+array.size());
					}
					for(int i=0; i<array.size(); i++){
						json = array.getJSONObject(i);
						if(json!=null){
							points[i] = new GPSPoint(json.getDouble("x"), json.getDouble("y"));
						}
					}
				}
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		return true;
	}
	
	/**
	 * 批量转换GPS坐标2百度地图坐标
	 * <p>Title: BMap2GPSHttp</p>
	 * <p>Description: 
	 * 		通过百度地图API转换GPS坐标2百度坐标
	 * </p>
	 * @param points
	 * @return
	 * 		转换后的返回数据，可参考百度地图API GPS坐标转换
	 * 		e.g:
	 *	 		{"status":0,"result":[{"x":114.23075574258,"y":29.579081083867},{"x":114.23075168254,"y":29.579086183217}]}
	 */
	public static String GPS2BMapHttp(GPSPoint [] points){
		
		String baiduconverturl;
		if(points==null)
			return null;
		String coords="";
		int sumpoint = 0;
		for(GPSPoint point : points){
			if(point!=null){
				sumpoint ++ ;
				if(sumpoint>1)
					coords += ";";
				coords += point.getLongitude()+","+point.getLatitude();
			}
		}
		if(coords.trim().isEmpty())
			return null;
		baiduconverturl = BMAP_CONVERT_URL +
				"coords="+ coords +
				"&from=1" +
				"&to=5" +
				"&ak="+BAIDU_KEY +
				"&output=json";
		return Convert.GPS2BMapHttp(0, 0, baiduconverturl);
	}
	
	/**
	 * 转换GPS坐标2百度地图坐标
	 * <p>Title: BMap2GPSHttp</p>
	 * <p>Description: 
	 * 		通过百度地图API转换GPS坐标2百度坐标
	 * </p>
	 * @param longitude : 经度
	 * @param latitude  : 纬度
	 * @param baiduconverturl 
	 * 			百度地图API转换全路径URL,e.g: http://api.map.baidu.com/geoconv/v1/?coords=114.21892734521,29.575429778924;114.21892734521,29.575429778924&from=1&to=5&ak=15EdmORyQbzDsGOQHiTsW2oh&output=json
	 * 			如果null，则使用默认的地址进行转换 
	 * 
	 * @see com.tool.tmap.Convert#BMap2GPS(double longitude, double latitude)	
	 * @return
	 * 		转换后的返回数据，可参考百度地图API GPS坐标转换
	 * 		e.g:
	 *	 		{"status":0,"result":[{"x":114.23075574258,"y":29.579081083867},{"x":114.23075168254,"y":29.579086183217}]}
	 */
	public static String GPS2BMapHttp(double longitude, double latitude, String baiduconverturl){
		
		String url = BMAP_CONVERT_URL +
				"coords="+longitude+","+latitude+"" +
				"&from=1" +
				"&to=5" +
				"&ak="+BAIDU_KEY +
				"&output=json";
		if(baiduconverturl!=null){
			url = baiduconverturl; 
		}
		
		HttpClient httpclient = new DefaultHttpClient();
		HttpGet httpget = new HttpGet(url);
		try {
			HttpResponse httpResponse = httpclient.execute(httpget);
			HttpEntity entity = httpResponse.getEntity();
			String html = EntityUtils.toString( entity );
			httpget.releaseConnection();
			return html;
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}
